package com.cjs.hegui30.config;

import android.content.Context;
import android.database.Cursor;
import android.os.Handler;
import android.os.Looper;
import com.cjs.hegui30.ConfigProvider;
import com.cjs.hegui30.model.ApiConfig;
import com.google.gson.Gson;
import de.robv.android.xposed.XposedBridge;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class PrivacyApiManager {
    private static final String CONFIG_PATH = "/config/privacy_api.json";
    private static final String DEFAULT_HOST = "127.0.0.1";
    private static final String DEFAULT_PORT = "8080";
    private static volatile PrivacyApiManager instance;
    private final OkHttpClient client;
    private final Gson gson;
    private volatile Map<String, HookConfig> apiHooks = new HashMap<>();
    private volatile long lastUpdateTime = 0;
    private static final long UPDATE_INTERVAL = 5 * 60 * 1000; // 5分钟更新一次

    public static class HookConfig {
        public final String tag;
        public final String description;

        public HookConfig(String tag, String description) {
            this.tag = tag;
            this.description = description;
        }
    }

    private PrivacyApiManager() {
        client = new OkHttpClient.Builder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .build();
        gson = new Gson();
        initializeDefaultConfig();
    }

    public static PrivacyApiManager getInstance() {
        if (instance == null) {
            synchronized (PrivacyApiManager.class) {
                if (instance == null) {
                    instance = new PrivacyApiManager();
                }
            }
        }
        return instance;
    }

    public void loadConfigSync(final Context context, final CountDownLatch loadLatch) {
        if (context == null) {
            XposedBridge.log("[Privacy] Context为空，无法加载配置");
            if (loadLatch != null)
                loadLatch.countDown();
            return;
        }

        String serverUrl = getServerUrl(context);
        if (serverUrl == null) {
            XposedBridge.log("[Privacy] 无法获取服务器地址，使用默认配置");
            if (loadLatch != null)
                loadLatch.countDown();
            return;
        }

        XposedBridge.log("[Privacy] 开始加载配置...");
        loadConfigFromServer(serverUrl, loadLatch);
    }

    public void tryLoadConfig(final Context context) {
        if (context == null) {
            XposedBridge.log("[Privacy] Context为空，无法加载配置");
            return;
        }

        String serverUrl = getServerUrl(context);
        if (serverUrl != null) {
            new Thread(() -> loadConfigFromServer(serverUrl, null)).start();
        }
    }

    private void loadConfigFromServer(String serverUrl, final CountDownLatch loadLatch) {
        String url = serverUrl + CONFIG_PATH;
        XposedBridge.log("[Privacy] 尝试从服务器加载配置: " + url);

        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                XposedBridge.log("[Privacy] 加载服务器配置失败: " + e.getMessage());
                if (loadLatch != null) {
                    loadLatch.countDown();
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    if (response.isSuccessful() && response.body() != null) {
                        String json = response.body().string();
                        final ApiConfig config = gson.fromJson(json, ApiConfig.class);
                        updateApiHooks(config);
                        lastUpdateTime = System.currentTimeMillis();
                        XposedBridge.log("[Privacy] 成功从服务器加载配置，版本: " + config.getVersion());
                    } else {
                        XposedBridge.log("[Privacy] 加载配置失败，HTTP状态码: " + response.code());
                    }
                } catch (Exception e) {
                    XposedBridge.log("[Privacy] 解析配置失败: " + e.getMessage());
                } finally {
                    response.close();
                    if (loadLatch != null) {
                        loadLatch.countDown();
                    }
                }
            }
        });
    }

    private void initializeDefaultConfig() {
        XposedBridge.log("[Privacy] 初始化默认API配置");

        // 设备标识相关
        addHook("android.telephony.TelephonyManager.getDeviceId", "DEVICE_ID", "获取设备ID");
        addHook("android.telephony.TelephonyManager.getImei", "DEVICE_ID", "获取IMEI");
        addHook("android.telephony.TelephonyManager.getMeid", "DEVICE_ID", "获取MEID");
        addHook("android.os.Build.getSerial", "DEVICE_ID", "获取序列号");

        // 位置相关
        addHook("android.location.LocationManager.getLastKnownLocation", "LOCATION", "获取最后位置");
        addHook("android.location.LocationManager.requestLocationUpdates", "LOCATION", "请求位置更新");
        addHook("android.location.Location.getLatitude", "LOCATION", "获取纬度");
        addHook("android.location.Location.getLongitude", "LOCATION", "获取经度");

        // 权限相关
        addHook("android.app.Activity.requestPermissions", "PERMISSION", "请求权限");
        addHook("android.content.Context.checkSelfPermission", "PERMISSION", "检查权限");

        // 其他基本的隐私API
        addHook("android.hardware.Camera.open", "CAMERA", "打开相机");
        addHook("android.media.MediaRecorder.start", "MICROPHONE", "使用麦克风");
        addHook("android.content.ClipboardManager.getPrimaryClip", "CLIPBOARD", "读取剪贴板");
    }

    private void addHook(String methodPath, String tag, String description) {
        apiHooks.put(methodPath, new HookConfig(tag, description));
    }

    private String getServerUrl(Context context) {
        try {
            if (context == null) {
                return null;
            }

            Cursor cursor = context.getContentResolver().query(
                    ConfigProvider.CONTENT_URI,
                    null,
                    null,
                    null,
                    null);

            if (cursor != null) {
                String address = "";
                String port = DEFAULT_PORT;

                while (cursor.moveToNext()) {
                    String key = cursor.getString(cursor.getColumnIndex("key"));
                    String value = cursor.getString(cursor.getColumnIndex("value"));
                    if ("server_address".equals(key)) {
                        address = value;
                    } else if ("server_port".equals(key)) {
                        port = value;
                    }
                }
                cursor.close();

                if (!address.isEmpty()) {
                    return "http://" + address + ":" + port;
                }
            }
        } catch (Exception e) {
            XposedBridge.log("[Privacy] Error getting server URL: " + e.getMessage());
        }
        return null;
    }

    public void updateConfigIfNeeded(String serverUrl) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastUpdateTime < UPDATE_INTERVAL) {
            return;
        }

        // 异步更新配置
        new Thread(new Runnable() {
            @Override
            public void run() {
                loadConfigFromServer(serverUrl, null);
            }
        }).start();
    }

    private void updateApiHooks(ApiConfig config) {
        Map<String, HookConfig> newHooks = new HashMap<>();

        for (Map.Entry<String, ApiConfig.ApiCategory> entry : config.getApis().entrySet()) {
            ApiConfig.ApiCategory category = entry.getValue();
            for (String method : category.getMethods()) {
                newHooks.put(method, new HookConfig(category.getTag(), category.getDescription()));
            }
        }

        synchronized (this) {
            apiHooks = newHooks;
            XposedBridge.log("[Privacy] 已更新API配置，共" + apiHooks.size() + "个API");
        }
    }

    public HookConfig getHookConfig(String methodPath) {
        return apiHooks.get(methodPath);
    }

    public boolean hasConfig(String methodPath) {
        return apiHooks.containsKey(methodPath);
    }

    public Map<String, HookConfig> getAllConfigs() {
        return new HashMap<>(apiHooks);
    }
}
